/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package rpt.bd.cenario;

import java.awt.Component;
import java.awt.Font;
import java.awt.Rectangle;
import java.math.BigDecimal;
import java.text.DecimalFormat;
import java.text.SimpleDateFormat;
import java.util.Collections;
import java.util.Date;
import java.util.Vector;
import javax.swing.JLabel;
import javax.swing.JTable;
import javax.swing.JTextField;
import javax.swing.ListSelectionModel;
import javax.swing.SwingConstants;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import javax.swing.table.DefaultTableCellRenderer;
import javax.swing.table.DefaultTableColumnModel;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.JTableHeader;
import javax.swing.table.TableCellRenderer;
import javax.swing.table.TableColumn;
import javax.swing.table.TableColumnModel;
import javax.swing.table.TableModel;

/**
 *
 * @author Roberto
 */
public class CGrade extends JTable {

    protected String[] fListaCabecalhoModeloGradeBd = null;
    protected Object[][] fListaObjetoModeloGradeBd = null;
    protected JTableHeader fCabecalhoGradeBd = null;
    protected CConjuntoDadosBd fConjuntoDadosBd;
    protected CModeloGrade fModeloGrade = null;

    public CGrade(boolean aPreparar) {
        super();
        preparar(aPreparar);
    }

    public void preparar(boolean aPreparar) {
        if (!aPreparar) return;
        TableModel tm = this.getModel();
        if (!(tm instanceof CModeloGrade)) {
            setModel(getModeloGrade());
        }
        setAutoCreateColumnsFromModel(false);
        setRowSelectionAllowed(true);
        setColumnSelectionAllowed(false);
        this.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
        ListSelectionModel vSelectionModel = getSelectionModel();
        prepararRegistroAtual();
        //
        addFocusListener(new java.awt.event.FocusAdapter() {
            @Override
            public void focusGained(java.awt.event.FocusEvent evt) {
                //setFocado(evt);
            }
        });        //
        vSelectionModel.addListSelectionListener(
            new ListSelectionListener() {
                public void valueChanged(ListSelectionEvent event) {
                    eventoSelecionar(event);
                }
            }
        );
        fCabecalhoGradeBd = getTableHeader();
        fCabecalhoGradeBd.setUpdateTableInRealTime(true);
        fCabecalhoGradeBd.addMouseListener(new COuvinteColunaGradeBd(this));
        fCabecalhoGradeBd.setReorderingAllowed(true);
        TableColumnModel tcm = getColumnModel();
        int cc = tcm.getColumnCount();
        for (int i=0; i < cc; i++) {
            TableColumn col = tcm.getColumn(i);
            //col.setCellRenderer(new MyTableCellRenderer());
        }
        setShowGrid(true);
    }

    public class MyTableCellRenderer extends JLabel implements TableCellRenderer {

        public MyTableCellRenderer() {
            setFont(fFonte); // NOI18N
        }

        Font fFonte = new java.awt.Font("Arial", 0, 10);
        DecimalFormat fFormatoDecimalInteger = new DecimalFormat("000");
        DecimalFormat fFormatoDecimalFloat = new DecimalFormat("#,##0.00");
        //
        // This method is called each time a cell in a column
        // using this renderer needs to be rendered.
        public Component getTableCellRendererComponent(JTable table, Object value,
                boolean isSelected, boolean hasFocus, int rowIndex, int colIndex) {
            // 'value' is value contained in the cell located at
            // (rowIndex, vColIndex)

            if (isSelected) {
                // cell (and perhaps other cells) are selected
            }

            if (hasFocus) {
                // this cell is the anchor and the table has the focus
            }
/*
            NumberFormatter nf = new NumberFormatter(java.text.NumberFormat.getCurrencyInstance());
            DefaultFormatterFactory dff = new DefaultFormatterFactory(nf);
            setFormatterFactory(dff);
            setHorizontalAlignment(JTextField.RIGHT);
            //
            //TableColumn tc = table.getColumnModel().getColumn(colIndex);
            //this.setSize(new Dimension(table.getRowHeight(),tc.getWidth()));
*/
            // Configure the component with the specified value
                if (value instanceof Integer) {
                setHorizontalAlignment(JTextField.RIGHT);
                setText(fFormatoDecimalInteger.format((Integer)value));
            }
            else
            if (value instanceof BigDecimal) {
                setHorizontalAlignment(JTextField.RIGHT);
                setText(fFormatoDecimalFloat.format((BigDecimal)value));
            }
            else
            if (value instanceof Date) {
                setHorizontalAlignment(JTextField.LEFT);
                SimpleDateFormat sdf = new SimpleDateFormat("dd/MM/yyyy");
                String s = sdf.format((Date)value);
                setText(s);
            }
            else {
                setHorizontalAlignment(JTextField.LEFT);
                if (value == null)
                    setText("???");
                else
                    setText(value.toString());
            }
/*
            try {
                commitEdit();
            } catch (ParseException ex) {
                Logger.getLogger(CJanelaLeitorTexto.class.getName()).log(Level.SEVERE, null, ex);
            }
*/
            // Set tool tip if desired
//          setToolTipText((String)value);

            // Since the renderer is a component, return itself
            return this;
        }

        // The following methods override the defaults for performance reasons
        @Override
        public void validate() {}
        @Override
        public void revalidate() {}
        @Override
        protected void firePropertyChange(String propertyName, Object oldValue, Object newValue) {}
        @Override
        public void firePropertyChange(String propertyName, boolean oldValue, boolean newValue) {}
    }

    /**************************************************************************/
    /***                                                                    ***/
    /**************************************************************************/

    protected CModeloGrade getModeloGrade() {
        return null;
    }

    /**************************************************************************/
    /***                                                                    ***/
    /**************************************************************************/

    public void eventoSelecionar(ListSelectionEvent event) {

    }

    /**************************************************************************/
    /***                                                                    ***/
    /**************************************************************************/

    public void prepararRegistroAtual() {
        eventoAntesPreparacaoRegistroAtual();
        CConjuntoDadosBd cd = getConjuntoDadosBd();
        Vector d = cd.getConjuntoDados();
        if (d.size() > 0) {
            changeSelection(0,0,false,false);
            CRegistroBd r = (CRegistroBd)d.get(0);
            setRegistroBdAnterior(r);
            setRegistroBdLinhaAnterior(0);
            setRegistroBdAtual(r);
            setRegistroBdLinhaAtual(0);
            getRegistroBdAtual().atualizarPainelBd(false);
        } else {
            setRegistroBdAnterior(null);
            setRegistroBdLinhaAnterior(-1);
            setRegistroBdAtual(null);
            setRegistroBdLinhaAtual(-1);
        }
        setRegistroBdAnterior(null);
        setRegistroBdLinhaAnterior(-1);
        eventoDepoisPreparacaoRegistroAtual();
    }

    /**************************************************************************/
    /***                                                                    ***/
    /**************************************************************************/

    protected void eventoAntesPreparacaoRegistroAtual() {
    }

    /**************************************************************************/
    /***                                                                    ***/
    /**************************************************************************/

    protected void eventoDepoisPreparacaoRegistroAtual() {
    }

    /**************************************************************************/
    /***                                                                    ***/
    /**************************************************************************/

    public void autoResizeColWidth() {
        setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
        setModel(getModeloGrade());

        int margin = 5;

        for (int i = 0; i < getColumnCount(); i++) {
            int                     vColIndex = i;
            DefaultTableColumnModel colModel  = (DefaultTableColumnModel) getColumnModel();
            TableColumn             col       = colModel.getColumn(vColIndex);
            int                     width     = 0;

            // Get width of column header
            TableCellRenderer renderer = col.getHeaderRenderer();

            if (renderer == null) {
                renderer = getTableHeader().getDefaultRenderer();
            }

            Component comp = renderer.getTableCellRendererComponent(this, col.getHeaderValue(), false, false, 0, 0);

            width = comp.getPreferredSize().width;

            // Get maximum width of column data
            for (int r = 0; r < getRowCount(); r++) {
                renderer = getCellRenderer(r, vColIndex);
                comp = renderer.getTableCellRendererComponent(this, getValueAt(r, vColIndex), false, false,
                        r, vColIndex);
                width = Math.max(width, comp.getPreferredSize().width);
            }

            // Add margin
            width += 2 * margin;

            // Set the width
            col.setPreferredWidth(width);
        }

        ((DefaultTableCellRenderer) getTableHeader().getDefaultRenderer()).setHorizontalAlignment(
            SwingConstants.LEFT);

        // table.setAutoCreateRowSorter(true);
        getTableHeader().setReorderingAllowed(false);

        return;
    }

    /**************************************************************************/
    /***                                                                    ***/
    /**************************************************************************/

    private void setFocado(java.awt.event.FocusEvent evt) {
    }

    /**************************************************************************/
    /***                                                                    ***/
    /**************************************************************************/

    public void setRegistroBdAtual(int aLinhaRegistroBd) {
        DefaultTableModel m = (DefaultTableModel)getModel();
        Vector dv = m.getDataVector();
        setRegistroBdAnterior(getRegistroBdAtual());
        setRegistroBdLinhaAnterior(getRegistroBdLinhaAtual());
        setRegistroBdAtual((CRegistroBd)dv.get(aLinhaRegistroBd));
        setRegistroBdLinhaAtual(aLinhaRegistroBd);
    }

    public void atualizar() {
        DefaultTableModel dtm = (DefaultTableModel)this.getModel();
        dtm.fireTableDataChanged();
        if (getRegistroBdLinhaAtual() >= 0)
          changeSelection(getRegistroBdLinhaAtual(),0,false,false);
    }

    public void Incluir() {

    }

    protected void changeSelectionModel( ListSelectionModel sm, int index,
                                       boolean toggle, boolean extend, boolean selected )
    {
        if( extend )
        {
            if( toggle )
            {
                sm.setAnchorSelectionIndex( index );
            }
            else
            {
                sm.setSelectionInterval( sm.getAnchorSelectionIndex(), index );
            }
        }
        else
        {
            if( toggle )
            {
                if( selected )
                {
                    sm.removeSelectionInterval( index, index );
                }
                else
                {
                    sm.addSelectionInterval( index, index );
                }
            }
            else
            {
                sm.setSelectionInterval( index, index );
            }
        }
    }

    /**
     * Overites same method in the JTable that was doing the scrollToRect for the selected cell.
     * Not it does scrollToRect for the selected row.
     */

    @Override
    public void changeSelection( int rowIndex, int columnIndex, boolean toggle, boolean extend )
    {
        ListSelectionModel rsm = getSelectionModel();
        ListSelectionModel csm = getColumnModel().getSelectionModel();

        boolean selected = isCellSelected( rowIndex, columnIndex );

        //alter code here to select only the first cell on the row if you want
        changeSelectionModel( csm, columnIndex, toggle, extend, selected );
        changeSelectionModel( rsm, rowIndex, toggle, extend, selected );

        // Scroll after changing the selection as blit scrolling is immediate,
        // so that if we cause the repaint after the scroll we end up painting
        // everything!
        if( getAutoscrolls() )
        {
            int columnNumbers = getColumnCount();
            //first cell on row
            Rectangle r1 = getCellRect( rowIndex, 0, true );
            //second cell on row
            Rectangle r2 = getCellRect( rowIndex, columnNumbers-1, true );
            if( r1 != null && r2 != null  )
            {
                Rectangle scrollToRect = new Rectangle( (int)r1.getX(),
                        (int)r1.getY(),
                        (int)(r2.getX() + r2.getWidth() - r1.getX()),
                        (int)r1.getHeight() );
                scrollRectToVisible( scrollToRect );
            }
        }
    }

    /**************************************************************************/
    /***                                                                    ***/
    /**************************************************************************/

    public CRegistroBd getRegistroBdAtual() {
        return fConjuntoDadosBd.getRegistroBdAtual();
    }

    /**************************************************************************/
    /***                                                                    ***/
    /**************************************************************************/

    public void setRegistroBdAtual(CRegistroBd aRegistroBdAtual) {
        fConjuntoDadosBd.setRegistroBdAtual(aRegistroBdAtual);
    }

    /**************************************************************************/
    /***                                                                    ***/
    /**************************************************************************/

    public int getRegistroBdLinhaAtual() {
        return fConjuntoDadosBd.getRegistroBdLinhaAtual();
    }

    /**************************************************************************/
    /***                                                                    ***/
    /**************************************************************************/

    public void setRegistroBdLinhaAtual(int aRegistroBdLinhaAtual) {
        fConjuntoDadosBd.setRegistroBdLinhaAtual(aRegistroBdLinhaAtual);
    }

    /**************************************************************************/
    /***                                                                    ***/
    /**************************************************************************/

    public CRegistroBd getRegistroBdAnterior() {
        return fConjuntoDadosBd.getRegistroBdAnterior();
    }

    /**************************************************************************/
    /***                                                                    ***/
    /**************************************************************************/

    public void setRegistroBdAnterior(CRegistroBd aRegistroBdAnterior) {
        fConjuntoDadosBd.setRegistroBdAnterior(aRegistroBdAnterior);
    }

    /**************************************************************************/
    /***                                                                    ***/
    /**************************************************************************/

    public int getRegistroBdLinhaAnterior() {
        return fConjuntoDadosBd.getRegistroBdLinhaAnterior();
    }

    /**************************************************************************/
    /***                                                                    ***/
    /**************************************************************************/

    public void setRegistroBdLinhaAnterior(int aRegistroBdLinhaAnterior) {
        fConjuntoDadosBd.setRegistroBdLinhaAnterior(aRegistroBdLinhaAnterior);
    }

    /**************************************************************************/
    /***                                                                    ***/
    /**************************************************************************/

    public Vector getCabecalhoGradeBd() {

        Vector vVetorCabecalho = new Vector();
        int vNumItensCabecalhoBd = getNumCamposCabecalhoBd();
        fListaCabecalhoModeloGradeBd = new String[vNumItensCabecalhoBd];
        CEstruturaCampoRegistroBd vEstruturaCampoRegistroBd = null;
        CEstruturaRegistroBd vEstruturaRegistroBd = getEstruturaRegistroBd();
        int vNumItensEstruturaRegistroBd = vEstruturaRegistroBd.getNumCamposRegistroBd();
        for (int vContador = 0; vContador < vNumItensEstruturaRegistroBd; vContador++) {
            vEstruturaCampoRegistroBd = vEstruturaRegistroBd.getEstruturaCampoRegistroBd(vContador);
            if (vEstruturaCampoRegistroBd.getCampoGradeBd())
                vVetorCabecalho.add(vEstruturaCampoRegistroBd.getTitulo());
                //fListaCabecalhoModeloGradeBd[vContador] = vEstruturaCampoRegistroBd.getNomeBD();
        }
        return vVetorCabecalho;
    }

    /**************************************************************************/
    /***                                                                    ***/
    /**************************************************************************/

    protected int getNumCamposCabecalhoBd() {
        return 0;
    }

    /**************************************************************************/
    /***                                                                    ***/
    /**************************************************************************/

    protected CEstruturaRegistroBd getEstruturaRegistroBd() {
        return null;
    }

    /**************************************************************************/
    /***                                                                    ***/
    /**************************************************************************/
/*
    public void adicionarRegistroBd(ResultSet aRs) {
        Vector v = new Vector();
        CEstruturaCampoRegistroBd vEstruturaCampoRegistroBd = null;
        CEstruturaRegistroBdCenarioEdicao vEstruturaRegistroBd = fPertinenciaBd.getEstruturaRegistroBd();
        int vNumItensEstruturaRegistroBd = vEstruturaRegistroBd.getNumCamposRegistroBd();
        for (int vContador = 0; vContador < vNumItensEstruturaRegistroBd; vContador++) {
            vEstruturaCampoRegistroBd = vEstruturaRegistroBd.getEstruturaCampoRegistroBd(vContador);
            if (vEstruturaCampoRegistroBd.getCampoGradeBd()) {
                CCampoRegistroBd s = new CCampoRegistroBd(null,vEstruturaCampoRegistroBd,aRs);
                v.add(s);
            }
        }
        //v.add(null);
        //fModeloGrade.addRow(v);
    }
*/
    /**************************************************************************/
    /***                                                                    ***/
    /**************************************************************************/

    public void ordenar(CModeloGrade aModeloGrade) {
        COrdenadorGradeBd o = new COrdenadorGradeBd(
                aModeloGrade.getIndiceColunaOrdenada(),
                aModeloGrade.getOrdenacaoAscendente());
        Collections.sort(getConjuntoDadosBd().getConjuntoDados(),o);
        aModeloGrade.fireTableStructureChanged();
    }

    /**************************************************************************/
    /***                                                                    ***/
    /**************************************************************************/

    public CConjuntoDadosBd getConjuntoDadosBd() {
        return null;
    }

    /**************************************************************************/
    /***                                                                    ***/
    /**************************************************************************/

    public void atualizarCampoRegistroBd(
        CRegistroBd aRegistroBd, Component aComponente, CCampoRegistroBd aCampoRegistroBd) {
        //
/*
        Component vComponente = null;
        CCampoRegistroBd vCampoRegistroBd = null;
        CEstruturaCampoRegistroBd e = null;
        if (aComponente == null) {
            if (aCampoRegistroBd == null) {
                return;
            }
            else
            {
                vCampoRegistroBd = aCampoRegistroBd;
                e = vCampoRegistroBd.getEstruturaCampoRegistroBd();
                vComponente = vCampoRegistroBd.getEstruturaCampoRegistroBd().getComponente();
            }
        }
        else {
            vComponente = aComponente;
            vCampoRegistroBd = aRegistroBd.getCampoRegistroBdComponente(vComponente);
            e = vCampoRegistroBd.getEstruturaCampoRegistroBd();
            if (e instanceof CEstruturaCampoRegistroBdLookup) {
                CEstruturaCampoRegistroBdLookup el = (CEstruturaCampoRegistroBdLookup)e;
                CCampoRegistroBd c = el.getCampoBdChavePrimaria();
                vCampoRegistroBd.setValorCampoBd(c.getValorCampoBdStr());
//              vCampoRegistroBd.setValorCampoBd(el.getValorChavePrimariaStr());
            }
            else {
                //vCampoRegistroBd.setValorCampoBd(e.getValorComponenteStr());
                Object o = vCampoRegistroBd.getValorComponente();
                vCampoRegistroBd.setValorCampoBd(o);
            }
            e.setCores(true,vCampoRegistroBd.getIgualOriginal());
        }
*/
        if (aRegistroBd == null) return;
        CCampoRegistroBd vCampoRegistroBd = aRegistroBd.atualizarCampoRegistroBd(aComponente,aCampoRegistroBd);
        if (vCampoRegistroBd == null) return;
        Component vComponente = vCampoRegistroBd.getEstruturaCampoRegistroBd().getComponente();
        CEstruturaCampoRegistroBd e = vCampoRegistroBd.getEstruturaCampoRegistroBd();
        if ((e.getCampoGradeBd()) && (vComponente != null)) {
            CModeloGrade mg = (CModeloGrade)getModel();
            int vRow = getRegistroBdLinhaAtual();
            int vCol = aRegistroBd.getIndiceCampoRegistroBdComponente(vComponente);
            mg.setValueAt(vCampoRegistroBd.getValorComponenteCampoBdStr(),vRow,vCol);
        }
    }

    public boolean getRolar() {
        return true;
    }

}
